package service

import (
	"gitee.com/night-tc/gobige/common"
	"gitee.com/night-tc/gobige/etcd"
	"gitee.com/night-tc/gobige/global"
	"gitee.com/night-tc/gobige/logger"
	"gitee.com/night-tc/gobige/msgdef/protomsg"
	"gitee.com/night-tc/gobige/serverMgr"
	"gitee.com/night-tc/gobige/sess"
)

/*
实现serverMgr.IExt
*/

// 根据类型生成一个新的IServerInfo对象，用与从etcd读出来后进行填充
func (this *Service) NewInfo(stype global.ServerTypeEnum) serverMgr.IServerInfo {
	return new(serverMgr.ServerInfo)
}

// 获取自己服务器需要注册的信息
func (this *Service) GetSelfInfo() serverMgr.IServerInfo {
	result := new(serverMgr.ServerInfo)
	result.Number = this.Sinfo.Number
	result.ServerID = this.Sinfo.ServerID
	result.GroupID = this.Sinfo.GroupID
	result.SrvType = this.Sinfo.SrvType
	result.OthGroupID = this.Sinfo.OthGroupID
	result.ListenMap = this.ListenMap
	result.Token = this.Token
	result.Status = this.Status.Load()
	return result
}

// 获取到新的服务器信息的时候回调，一般用来判断是否需要连接这个服务器
func (this *Service) WatchInfoCallBack(sinfo serverMgr.IServerInfo) {
	/*
		判断是不是需要连接的服务器类型，如果是就连接这个服务器
	*/
	if this.Sinfo.GroupID == sinfo.GetGroupID() {
		// TODO:是同一组的
		if common.ArrayIndexof(this.Sinfo.ConSrvTypeList, sinfo.GetSrvType()) == -1 {
			//没找到
			return
		}
	} else if this.Sinfo.OthGroupID == sinfo.GetGroupID() {
		// TODO:是同一组的
		if common.ArrayIndexof(this.Sinfo.OthConSrvTypeList, sinfo.GetSrvType()) == -1 {
			//没找到
			return
		}
	}

	if this.GetClientSess(sinfo.GetServerID()) != nil {
		return
	}
	if _, ok := this.pendingSesses.Load(sinfo.GetServerID()); ok {
		logger.Infof("WatchInfoCallBack pendingSesses already exist. %d ", sinfo.GetServerID())
		return
	}
	sessmd, err := sess.Dial(this.GetProtocal(), this.real, sinfo.GetListenAdd(global.ListenType_Inner), this.thgo)
	if err != nil {
		logger.Error("Error connecting", err)
		return
	}
	sessmd.SetID(sinfo.GetServerID())
	sessmd.SetType(sinfo.GetSrvType())
	msgh := this.MsgHandler.GetNewSubHandler()
	//服务器主动连接别的服务器的时候,需要做一下连接出来的消息
	msgh.RegMsgProc(&NetSess_Proc{
		Srv:  this,
		Sess: sessmd,
	})
	sessmd.SetMsgHandler(msgh)
	sessmd.Start()
	logger.Infof("WatchInfoCallBack ID: %d Type: %d.", sessmd.GetID(), sessmd.GetType())
	this.pendingSesses.Store(sinfo.GetServerID(), sessmd)
	sessmd.Send(&protomsg.ClientVerifyReq{
		SessUID:   this.Sinfo.GetServerID(),
		SessType:  this.Sinfo.GetSrvType(),
		SessState: 1,
		Token:     sinfo.GetToken(),
	})
}

// 获取ETCD的实例
func (this *Service) GetEtcd() *etcd.EtcdAccess {
	return this.Etcd
}

// 获取服务器负载器
func (this *Service) GetDirMgr() *serverMgr.DiscoveryMgr {
	return this.DisMgr
}
